﻿using System.Windows;
using System.Windows.Controls;

namespace SHomeWorkshop.LunarPresentation.Commands
{
    public partial class Command
    {

        public static void EmbedToBracket()
        {
            EmbedToAnotherExpression(TypeOfExpression.Bracket,
                LunarPresentation.Properties.Resources.Bracket);
        }

        public static void EmbedToOneLTwoCGrid()
        {
            EmbedToAnotherExpression(TypeOfExpression.Grid,
                LunarPresentation.Properties.Resources.OneLTwoCGrid);
        }

        public static void EmbedToRow()
        {
            Expressions.Expression ex = EmbedToAnotherExpression(TypeOfExpression.Row,
                LunarPresentation.Properties.Resources.Row);
            if (ex is Expressions.Row)
            {
                Expressions.Row row = ex as Expressions.Row;
                if (row.FirstSubPanel != null &&
                    row.FirstSubPanel.BasePanel.Orientation == Orientation.Horizontal)
                {
                    foreach (UIElement ue in row.FirstSubPanel.BasePanel.Children)
                    {
                        Expressions.Expression childEx = ue as Expressions.Expression;

                        if (childEx != null)
                        {
                            childEx.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                            //水平子面板中默认是垂直居中的（只有根面板例外——根面板中默认居上对齐），
                            //但此处是嵌入，不必考虑根面板。
                        }
                    }
                }
            }
        }

        public static void EmbedToExpander()
        {
            EmbedToAnotherExpression(TypeOfExpression.Expander,
                LunarPresentation.Properties.Resources.Expander);
        }

        /// <summary>
        /// 嵌入某个公式，该公式类型的FirstPanel必须不为null。
        /// </summary>
        /// <param name="exType">要嵌入在其中的新公式的类型。</param>
        /// <param name="destExXml">新公式的Xml文本。</param>
        private static Expressions.Expression EmbedToAnotherExpression(TypeOfExpression exEype, string destExXml)
        {
            if (Globals.selectedEditor == null) return null;
            if (Globals.selectedEditor.SelectedExpression == null) return null;

            LunarPresentation.Expressions.Expression curEx
                = Globals.selectedEditor.SelectedExpression;

            if (curEx is Expressions.SubPanel)
            {
                System.Windows.MessageBox.Show("子面板不支持嵌入操作，只有普通公式才可以嵌入另一个公式中！",
                    Globals.appName, System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Warning);
                return null;
            }

            if (curEx is Expressions.BaseText)
            {
                Expressions.BaseText curBt = curEx as Expressions.BaseText;
                if (curBt.IsCollapsed)
                {
                    MessageBox.Show("折叠的标题文本块不允许被嵌入其它公式。此外“剪切、复制、粘贴、删除、平移、拖动、更改缩进、对齐”等操作亦被禁止。",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return null;
                }
            }

            if (curEx.Parent is StackPanel)
            {
                curEx.XmlData.InsertXml(destExXml);

                StackPanel spanel = curEx.Parent as StackPanel;

                LunarPresentation.Expressions.Expression newExpression = null;

                switch (exEype)// 此处不必支持所有公式类型。
                {
                    case TypeOfExpression.BaseText:
                        {
                            newExpression = new Expressions.BaseText(
                                curEx.RootPanel, curEx.ParentPanel, curEx.Editor); break;
                        }
                    case TypeOfExpression.Bracket:
                        {
                            newExpression = new Expressions.Bracket(
                                curEx.RootPanel, curEx.ParentPanel, curEx.Editor); break;
                        }
                    case TypeOfExpression.Expander:
                        {
                            newExpression = new Expressions.Expander(
                                curEx.RootPanel, curEx.ParentPanel, curEx.Editor); break;
                        }
                    case TypeOfExpression.Grid:
                        {
                            newExpression = new Expressions.Grid(
                                curEx.RootPanel, curEx.ParentPanel, curEx.Editor); break;
                        }
                    //case TypeOfExpression.PictureBox 图片框中不能嵌入。
                    case TypeOfExpression.Row:
                        {
                            newExpression = new Expressions.Row(
                                curEx.RootPanel, curEx.ParentPanel, curEx.Editor); break;
                        }
                    // TODO 如果有新公式类型，要注意添加。                    
                }

                if (newExpression == null) return null;

                spanel.Children.Insert(spanel.Children.IndexOf(curEx) + 1, newExpression);
                newExpression.XmlData = Globals.selectedEditor.SelectedExpression.XmlData.NextSibling;
                newExpression.Indent = curEx.Indent;// 插入新公式时自动同步缩进。

                ModifingItem mi = new ModifingItem() { OldSelectedExID = curEx.ExID };

                if (curEx.Indent != 0)
                {
                    Action actIndent = new Action(curEx.ExID, -1, curEx.GetType().Name,
                        "Indent", curEx.Indent.ToString(), "0");

                    curEx.Indent = 0;//此公式缩进已经被包装公式继承，则此公式自身不应再保留缩进。

                    mi.Add(actIndent);
                }

                if (curEx is Expressions.BaseText)
                {
                    curEx.ParentPanel.RefreshAutoNumbersOfBaseText();
                    Expressions.BaseText bt = curEx as Expressions.BaseText;

                    if (bt.FontSizeLevel != 0)
                    {
                        Action actFontSizeLevel = new Action(bt.ExID, -1,
                            bt.GetType().Name, "FontSizeLevel", bt.FontSizeLevel.ToString(), "0");

                        bt.FontSizeLevel = 0;//取消标题层级。

                        mi.Add(actFontSizeLevel);
                    }

                    if (bt.FontWeight != FontWeights.Normal)
                    {
                        Action actFontWeight = new Action(bt.ExID, -1,
                            bt.GetType().Name, "FontWeight", bt.FontWeight.ToString(),
                            FontWeights.Normal.ToString());

                        bt.FontWeight = FontWeights.Normal;

                        mi.Add(actFontWeight);
                    }

                    if (bt.FontStyle != FontStyles.Normal)
                    {
                        Action actFontStyle = new Action(bt.ExID, -1,
                            bt.GetType().Name, "FontStyle", bt.FontStyle.ToString(),
                            FontStyles.Normal.ToString());

                        bt.FontStyle = FontStyles.Normal;

                        mi.Add(actFontStyle);
                    }

                    if (bt.IsHeaderText)
                    {
                        Action actIsHeaderText = new Action(bt.ExID, -1,
                            bt.GetType().Name, "IsHeaderText", bt.IsHeaderText.ToString(),
                            false.ToString());

                        bt.IsHeaderText = false;

                        mi.Add(actIsHeaderText);
                    }
                }

                if (newExpression.FirstSubPanel != null)
                {
                    if (newExpression.FirstSubPanel.BasePanel != null)
                    {
                        if (newExpression.FirstSubPanel.BasePanel.Children.Count >= 1)
                        {
                            Expressions.Expression willDeleteEx
                                = newExpression.FirstSubPanel.BasePanel.Children[0] as Expressions.Expression;

                            if (willDeleteEx != null)
                            {
                                if (willDeleteEx.Parent is StackPanel)
                                {

                                    //注意这个加入的顺序：先实例化，后删除——不必担心索引值，因为已经插入了新包装式。
                                    Action actInsertEx = new Action(newExpression.ExID,
                                        newExpression.ParentPanel.BasePanel.Children.IndexOf(newExpression),
                                        newExpression.GetType().Name, "InsertExpression", null, newExpression.XmlData.OuterXml,
                                        ActionType.Insert, newExpression.ParentPanel.ExID);

                                    Action actDelSource = new Action(curEx.ExID, curEx.ParentPanel.BasePanel.Children.IndexOf(curEx),
                                        curEx.GetType().Name, "DeleteExpression", curEx.XmlData.OuterXml, null,
                                        ActionType.Delete, curEx.ParentPanel.ExID);

                                    curEx.XmlData.ParentNode.RemoveChild(curEx.XmlData);
                                    willDeleteEx.XmlData.ParentNode.AppendChild(curEx.XmlData);

                                    spanel.Children.Remove(curEx);
                                    curEx.ParentPanel = willDeleteEx.ParentPanel;

                                    (willDeleteEx.Parent as StackPanel).Children.Add(curEx);

                                    Action actInsertSource = new Action(curEx.ExID, curEx.ParentPanel.BasePanel.Children.IndexOf(curEx),
                                        curEx.GetType().Name, "InsertExpression", null, curEx.XmlData.OuterXml,
                                        ActionType.Insert, curEx.ParentPanel.ExID);

                                    willDeleteEx.XmlData.ParentNode.RemoveChild(willDeleteEx.XmlData);
                                    (willDeleteEx.Parent as StackPanel).Children.Remove(willDeleteEx);

                                    Action actDelElse = new Action(willDeleteEx.ExID, willDeleteEx.ParentPanel.BasePanel.Children.IndexOf(willDeleteEx),
                                        willDeleteEx.GetType().Name, "DeleteExpression", willDeleteEx.XmlData.OuterXml, null,
                                        ActionType.Delete, curEx.ParentPanel.ExID);

                                    if (newExpression.LastSubPanel != null)
                                    {
                                        Globals.selectedEditor.SelectedExpression
                                            = newExpression.LastSubPanel.BasePanel.Children[0] as Expressions.Expression;
                                    }

                                    //注意顺序。
                                    mi.Add(actInsertEx); mi.Add(actDelSource);
                                    mi.Add(actInsertSource); mi.Add(actDelElse);
                                    newExpression.Editor.Do(mi);

                                    newExpression.Editor.IsModified = true;
                                }
                            }
                        }
                        newExpression.FirstSubPanel.RefreshAutoNumbersOfBaseText();
                    }
                }

                return newExpression;
            }//如果curEx.Parent is StackPanel==false.
            return null;
        }

        /// <summary>
        /// 将指定子面板中所有公式嵌入一个[１行×２列]的网格式中。
        /// </summary>
        /// <param name="subPanel">目标子面板。</param>
        private static void EmbedAllChildrenToGrid(Expressions.SubPanel subPanel)
        {
            if (subPanel == null) return;

            string subPanelOldOutXmlText = subPanel.XmlData.OuterXml;

            Expressions.Grid grid = new Expressions.Grid(
                (subPanel.RootPanel == null || subPanel.RootPanel == subPanel) ? subPanel : subPanel.RootPanel,
                subPanel, subPanel.Editor);

            if (subPanel.XmlData.FirstChild.InsertXml(
                LunarPresentation.Properties.Resources.OneLTwoCGrid, false) == false) return;

            grid.XmlData = subPanel.XmlData.FirstChild;
            grid.FirstSubPanel.BasePanel.Children.Clear();
            grid.FirstSubPanel.XmlData.InnerXml = "";

            ModifingItem mi = new ModifingItem();

            for (int i = subPanel.BasePanel.Children.Count - 1; i >= 0; i--)
            {
                if (subPanel.BasePanel.Children[i] is Expressions.Expression)
                {
                    Expressions.Expression ex = subPanel.BasePanel.Children[i] as Expressions.Expression;

                    subPanel.BasePanel.Children.RemoveAt(i);
                    subPanel.XmlData.RemoveChild(ex.XmlData);

                    grid.FirstSubPanel.BasePanel.Children.Insert(0, ex);
                    grid.FirstSubPanel.XmlData.InsertBefore(ex.XmlData, grid.FirstSubPanel.XmlData.FirstChild);

                    //ex.RootPanel = grid.RootPanel;
                    //嵌入操作不能跨文档进行。此行多余。

                    ex.ParentPanel = grid.FirstSubPanel;
                }
            }

            subPanel.BasePanel.Children.Add(grid);

            Action action = new Action(subPanel.ExID, -1, subPanel.GetType().Name, "OutXmlText", subPanelOldOutXmlText,
                subPanel.XmlData.OuterXml);

            mi.Add(action);
            grid.Editor.Do(mi);

            subPanel.Editor.IsModified = true;
            subPanel.Editor.SelectedExpression = grid.LastSubPanel.BasePanel.Children[0] as Expressions.Expression;
        }

        public static void EmbedAllChildrenToGrid()
        {
            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;

            Expressions.SubPanel subPanel;
            if (Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
            {
                subPanel = Globals.selectedEditor.SelectedExpression as Expressions.SubPanel;

                if (System.Windows.MessageBox.Show("此操作将把当前子面板中所有公式嵌入一个[1行×2列]网格式中。要继续吗？",
                Globals.appName, System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Warning) !=
                System.Windows.MessageBoxResult.Yes)
                {
                    return;
                }

                Command.EmbedAllChildrenToGrid(subPanel);
            }
            else
            {
                subPanel = Globals.selectedEditor.SelectedExpression.ParentPanel;

                if (System.Windows.MessageBox.Show("此操作将把当前公式父面板中所有公式（包括当前公式）嵌入一个[1行×2列]网格式中。要继续吗？",
                Globals.appName, System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Warning) !=
                System.Windows.MessageBoxResult.Yes)
                {
                    return;
                }

                Command.EmbedAllChildrenToGrid(subPanel);
            }
        }
    }
}
